/*
 * Copyright (c) 2023 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "config_network.h"
#include "los_task.h"
#include "intelligent_agriculture.h"

ia_soil_humidity_t g_soil_humidity =
{
    .is_continue = 1,
    .voltage = 0,
    .value   = 0.0,
    .adc_dev =
    {
        .init  = 0,
        .port  = 4,
        .value = 0,
        .adc   = {
            .gpio = GPIO0_PC4,
            .func = MUX_FUNC1,
            .type = PULL_NONE,
            .drv = DRIVE_KEEP,
            .dir = LZGPIO_DIR_IN,
            .val = LZGPIO_LEVEL_KEEP
        },
    },
};

ia_light_intensity_t g_light_intensity =
{
    .is_continue = 1,
    .value   = 0.0,
    .i2c_dev =
    {
        .init       = 0,
        .port       = 0,
        .slave_addr = 0x23,
        .speed      = 100000,
        .i2c        =
        {
            .scl  =  {
                .gpio = GPIO0_PA1,
                .func = MUX_FUNC3,
                .type = PULL_NONE,
                .drv = DRIVE_KEEP,
                .dir = LZGPIO_DIR_KEEP,
                .val = LZGPIO_LEVEL_KEEP
            },
            .sda  =  {
                .gpio = GPIO0_PA0,
                .func = MUX_FUNC3,
                .type = PULL_NONE,
                .drv = DRIVE_KEEP,
                .dir = LZGPIO_DIR_KEEP,
                .val = LZGPIO_LEVEL_KEEP
            },
            .id   = FUNC_ID_I2C0,
            .mode = FUNC_MODE_M2,
        },
    },
};

ia_water_pump_t g_water_pump =
{
    .onoff     = 0,
    .relay_dev =
    {
        .init  = 0,
        .onoff = 0,
        .relay = {
            .gpio = GPIO0_PA2,
            .func = MUX_GPIO,
            .type = PULL_UP,
            .drv = DRIVE_KEEP,
            .dir = LZGPIO_DIR_OUT,
            .val = LZGPIO_LEVEL_HIGH
        },
    },
};

ia_shed_cover_t g_shed_cover =
{
    .onoff    = 0,
    .on_duty  = 500,
    .off_duty = 2500,
    .pwm_dev  =
    {
        .init    = 0,
        .port    = 7,
        .cycle   = 20000000,
        .pwmio =
        {
            .pwm  = {
                .gpio = GPIO1_PD0,
                .func = MUX_FUNC1,
                .type = PULL_DOWN,
                .drv = DRIVE_KEEP,
                .dir = LZGPIO_DIR_KEEP,
                .val = LZGPIO_LEVEL_KEEP
            },
            .id   = FUNC_ID_PWM7,
            .mode = FUNC_MODE_NONE,
        },
    },
};

ia_lcd_t g_lcd =
{
    .param = {
        .dir = 0,
        .f_color = LCD_LBBLUE,
        .b_color = LCD_WHITE,
        .f_size = 32,
        .start_line = IMAGE_H_SIEZ + 16
    },
};

// 智慧农业设备结构体包含所使用的外设参数的初始化
ia_dev_t g_ia_dev =
{
    .soil_humidity      = &g_soil_humidity,
    .light_intensity    = &g_light_intensity,
    .water_pump         = &g_water_pump,
    .shed_cover         = &g_shed_cover,
    .lcd                = &g_lcd,
};


/***************************************************************
* 函数名称: ia_adc_dev_init
* 说    明: 初始化ADC设备
* 参    数: ia_adc_dev_t *adc_dev
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_adc_dev_init(ia_adc_dev_t *adc_dev)
{
    if (PinctrlInit(adc_dev->adc) != 0)
    {
        printf("adc pin %d init failed\n", adc_dev->adc.gpio);
        return 1;
    }
    if (LzSaradcInit() != 0)
    {
        printf("saradc  %d init failed\n", adc_dev->port);
        return 1;
    }
    
    volatile GRF_SOC_CON29 *soc = (GRF_SOC_CON29 *)&GRF->SOC_CON29;
    /*配置ADC外部参考电压grf_saradc_vol_sel=0，内部参考电压grf_saradc_vol_sel=1,rw.grf_saradc_vol_sel对应位写使能*/
    soc->rw.grf_saradc_vol_sel = 1;
    soc->grf_saradc_vol_sel    = 0;
    soc->rw.grf_saradc_vol_sel = 0;
    
    adc_dev->init = 1;
    return 0;
}

/***************************************************************
* 函数名称: ia_i2c_dev_init
* 说    明: 初始化I2C设备
* 参    数: ia_i2c_dev_t *i2c_dev
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_i2c_dev_init(ia_i2c_dev_t *i2c_dev)
{
    /*初始化I2C*/
    if (I2cIoInit(i2c_dev->i2c) != LZ_HARDWARE_SUCCESS)
    {
        printf("init I2C I2C%d io failed\n", i2c_dev->port);
        return 1;
    }
    /*I2C时钟频率*/
    if (LzI2cInit(i2c_dev->port, i2c_dev->speed) != LZ_HARDWARE_SUCCESS)
    {
        printf("init I2C I2C%d failed\n", i2c_dev->port);
        return 1;
    }
    
    i2c_dev->init = 1;
    return 0;
}

/***************************************************************
* 函数名称: ia_relay_dev_init
* 说    明: 初始化继电器设备
* 参    数: ia_relay_dev_t *relay_dev
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_relay_dev_init(ia_relay_dev_t *relay_dev)
{
    if (PinctrlInit(relay_dev->relay) != 0)
    {
        printf("relay_dev pin %d init failed\n", relay_dev->relay.gpio);
        return 1;
    }
    
    relay_dev->init = 1;
    return 0;
}

/***************************************************************
* 函数名称: ia_pwm_dev_init
* 说    明: 初始化PWM设备
* 参    数: ia_pwm_dev_t *pwm_dev
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_pwm_dev_init(ia_pwm_dev_t *pwm_dev)
{
    if (PwmIoInit(pwm_dev->pwmio) != 0)
    {
        printf("Pwm%d pin%d io init failed\n", pwm_dev->port, pwm_dev->pwmio.pwm.gpio);
        return 1;
    }
    if (LzPwmInit(pwm_dev->port) != 0)
    {
        printf("Pwm%d pin%d init failed\n", pwm_dev->port, pwm_dev->pwmio.pwm.gpio);
        return 1;
    }
    
    pwm_dev->init = 1;
    return 0;
}

/***************************************************************
* 函数名称: ia_pwm_dev_start
* 说    明: pwm 启动
* 参    数: ia_pwm_dev_t *pwm_dev    pwm设备
*          uint32_t dutyus  占空比 us
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_pwm_dev_start(ia_pwm_dev_t *pwm_dev, uint32_t dutyus)
{
    if (pwm_dev->init == 0)
    {
        printf("PWM%d pin%d not init\n", pwm_dev->port, pwm_dev->pwmio.pwm.gpio);
        // return 1;
    }
    
    if (LzPwmStart(pwm_dev->port, dutyus * 1000, pwm_dev->cycle) != 0)
    {
        printf("PWM%d pin%d Start failed\n", pwm_dev->port, pwm_dev->pwmio.pwm.gpio);
        return 1;
    }
    pwm_dev->onoff = 1;
    return 0;
}

/***************************************************************
* 函数名称: ia_pwm_dev_stop
* 说    明: pwm 停止
* 参    数: ia_pwm_dev_t *pwm_dev     pwm设备
* 返 回 值: 0 成功，1 失败
***************************************************************/
static __attribute__((unused)) uint32_t ia_pwm_dev_stop(ia_pwm_dev_t *pwm_dev)
{
    if (pwm_dev->init == 0)
    {
        printf("PWM%d pin%d not init\n", pwm_dev->port, pwm_dev->pwmio.pwm.gpio);
        // return 1;
    }
    
    if (pwm_dev->onoff == 0)
    {
        return 0;
    }
    else if (LzPwmStop(pwm_dev->port) != 0)
    {
        printf("PWM%d pin%d Stop failed\n", pwm_dev->port, pwm_dev->pwmio.pwm.gpio);
        return 1;
    }
    pwm_dev->onoff = 0;
    return 0;
}

/***************************************************************
* 函数名称: ia_init_bh1750
* 说    明: 写命令初始化BH1750
* 参    数: ia_i2c_dev_t *i2c_dev
* 返 回 值: 无
***************************************************************/
static void ia_init_bh1750(ia_i2c_dev_t *i2c_dev)
{
    uint8_t send_data[1] = {0x01};
    uint32_t send_len = 1;
    
    LzI2cWrite(i2c_dev->port, i2c_dev->slave_addr, send_data, send_len);
}

/***************************************************************
* 函数名称: ia_start_bh1750
* 说    明: 启动BH1750
* 参    数: ia_i2c_dev_t *i2c_dev
* 返 回 值: 无
***************************************************************/
static void ia_start_bh1750(ia_i2c_dev_t *i2c_dev)
{
    uint8_t send_data[1] = {0x10};
    uint32_t send_len = 1;
    
    LzI2cWrite(i2c_dev->port, i2c_dev->slave_addr, send_data, send_len);
}

/***************************************************************
* 函数名称: ia_adc_read_value
* 说    明: 读取ADC值
* 参    数: ia_adc_dev_t *adc_dev ADC设备
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_adc_read_value(ia_adc_dev_t *adc_dev)
{
    if (adc_dev->init == 0)
    {
        printf("ADC%d not init\n", adc_dev->port);
        return 1;
    }
    else if (LzSaradcReadValue(adc_dev->port, &adc_dev->value) != 0)
    {
        printf("ADC%d read failed\n", adc_dev->port);
        return 1;
    }
    
    return 0;
}

/***************************************************************
* 函数名称: ia_get_voltage
* 说    明: 获取电压值
* 参    数: ia_adc_dev_t *adc_dev
* 返 回 值: float 电压值 v
***************************************************************/
static float ia_get_voltage(ia_adc_dev_t *adc_dev)
{
    if (ia_adc_read_value(adc_dev) != 0)
    {
        printf("get ch%d voltage failed\n", adc_dev->port);
    }
    
    return (float)adc_dev->value * 3.3  / 1024;
}

/***************************************************************
* 函数名称: ia_relay_dev_on
* 说    明: 打开继电器
* 参    数: ia_relay_dev_t *relay_dev
* 返 回 值: 成功 LZ_HARDWARE_SUCCESS, 失败 LZ_HARDWARE_FAILURE
***************************************************************/
static int ia_relay_dev_on(ia_relay_dev_t *relay_dev)
{
    int ret = 0;
    if (relay_dev->init == 0)
    {
        printf("relay dev not init\n");
    }
    ret = LzGpioSetVal(relay_dev->relay.gpio, LZGPIO_LEVEL_HIGH);
    if (ret == LZ_HARDWARE_SUCCESS)
    {
        relay_dev->onoff = ON;
    }
    return ret;
}

/***************************************************************
* 函数名称: ia_relay_dev_off
* 说    明: 关闭继电器
* 参    数: ia_relay_dev_t *relay_dev
* 返 回 值: 成功 LZ_HARDWARE_SUCCESS, 失败 LZ_HARDWARE_FAILURE
***************************************************************/
static int ia_relay_dev_off(ia_relay_dev_t *relay_dev)
{
    int ret = 0;
    if (relay_dev->init == 0)
    {
        printf("relay dev not init\n");
    }
    
    ret = LzGpioSetVal(relay_dev->relay.gpio, LZGPIO_LEVEL_LOW);
    if (ret == LZ_HARDWARE_SUCCESS)
    {
        relay_dev->onoff = OFF;
    }
    return ret;
}


/***************************************************************
* 函数名称: ia_water_pump_on
* 说    明: 打开水泵
* 参    数: ia_water_pump_t *water_pump
* 返 回 值: 无
***************************************************************/
static void ia_water_pump_on(ia_water_pump_t *water_pump)
{
    if (ia_relay_dev_on(&water_pump->relay_dev) == LZ_HARDWARE_SUCCESS)
    {
        water_pump->onoff = ON;
    }
}

/***************************************************************
* 函数名称: ia_water_pump_off
* 说    明: 关闭水泵
* 参    数: ia_water_pump_t *water_pump
* 返 回 值: 无
***************************************************************/
static void ia_water_pump_off(ia_water_pump_t *water_pump)
{
    if (ia_relay_dev_off(&water_pump->relay_dev) == LZ_HARDWARE_SUCCESS)
    {
        water_pump->onoff = OFF;
    }
}

/***************************************************************
* 函数名称: ia_shed_cover_on
* 说    明: 棚罩打开
* 参    数: ia_shed_cover_t *shed_cover
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_shed_cover_on(ia_shed_cover_t *shed_cover)
{
    if (shed_cover->onoff == ON)
    {
        return 0;
    }
    
    int ret = ia_pwm_dev_start(&shed_cover->pwm_dev, shed_cover->on_duty);
    if (ret == 0)
    {
        shed_cover->onoff = ON;
    }
    return ret;
}

/***************************************************************
* 函数名称: ia_shed_cover_off
* 说    明: 棚罩关闭
* 参    数: ia_shed_cover_t *shed_cover
* 返 回 值: 0 成功，1 失败
***************************************************************/
static uint32_t ia_shed_cover_off(ia_shed_cover_t *shed_cover)
{
    if (shed_cover->onoff == OFF)
    {
        return 0;
    }
    
    int ret = ia_pwm_dev_start(&shed_cover->pwm_dev, shed_cover->off_duty);
    if (ret == 0)
    {
        shed_cover->onoff = OFF;
    }
    return ret;
}

/***************************************************************
* 函数名称: ia_lcd_reset
* 说    明: lcd复位显示
* 参    数: ia_lcd_param_t lcd
* 返 回 值: 0 成功，1 失败
***************************************************************/
static void ia_lcd_reset(ia_lcd_param_t lcd)
{
    lcd_fill(0, 0, lcd.w, lcd.h, lcd.b_color);
    Printf_Lcd(0, 10, lcd.f_color, lcd.b_color, lcd.f_size, E_LCD_SCREEN_ALIGN_MID_NOP, "智慧农业");
    lcd_fill(0, lcd.start_line - 12, lcd.w, lcd.start_line - 4, lcd.f_color);
    lcd_fill(0, lcd.start_line + lcd.f_size * 2 + 12, lcd.w, lcd.start_line + lcd.f_size * 2 + 20, lcd.f_color);
    lcd_fill(0, lcd.h - 8, lcd.w, lcd.h, lcd.f_color);
}

/***************************************************************
* 函数名称: ia_soil_humidity_init
* 说    明: 土壤湿度传感器初始化
* 参    数: ia_soil_humidity_t *soil_humidity
* 返 回 值: 无
***************************************************************/
void ia_soil_humidity_init(ia_soil_humidity_t *soil_humidity)
{
    ia_adc_dev_init(&soil_humidity->adc_dev);
}

/***************************************************************
* 函数名称: ia_light_intensity_init
* 说    明: 光强传感器初始化
* 参    数: ia_light_intensity_t *light_intensity
* 返 回 值: 无
***************************************************************/
void ia_light_intensity_init(ia_light_intensity_t *light_intensity)
{
    ia_i2c_dev_init(&light_intensity->i2c_dev);
    ia_init_bh1750(&light_intensity->i2c_dev);
}

/***************************************************************
* 函数名称: ia_water_pump_init
* 说    明: 水泵初始化
* 参    数: ia_water_pump_t *water_pump
* 返 回 值: 无
***************************************************************/
void ia_water_pump_init(ia_water_pump_t *water_pump)
{
    ia_relay_dev_init(&water_pump->relay_dev);
    ia_water_pump_off(water_pump);
}

/***************************************************************
* 函数名称: ia_shed_cover_init
* 说    明: 棚罩初始化
* 参    数: ia_shed_cover_t *shed_cover
* 返 回 值: 无
***************************************************************/
void ia_shed_cover_init(ia_shed_cover_t *shed_cover)
{
    ia_pwm_dev_init(&shed_cover->pwm_dev);
    ia_shed_cover_off(shed_cover);
}

/***************************************************************
* 函数名称: ia_lcd_init
* 说    明: lcd初始化
* 参    数: ia_lcd_param_t *lcd_param
* 返 回 值: 无
***************************************************************/
void ia_lcd_init(ia_lcd_param_t *lcd_param)
{
    lcd_io_init();          // LCD初始化
    lcd_init(2);
    lcd_param->w = g_lcd_size.w;
    lcd_param->h = g_lcd_size.h;
    ia_lcd_reset(*lcd_param);
#define STR_WELCOME        "欢迎使用"
#define STR_SMART_HOUSE    "智慧农业"
    int len = get_str_size((char *)STR_WELCOME, lcd_param->f_size);
    lcd_left_move(lcd_param->w - len, LCD_LEFT_MOVE_EDN(lcd_param->w, (char *)STR_WELCOME, lcd_param->f_size), lcd_param->start_line + lcd_param->f_size * 0, lcd_param->f_color, lcd_param->b_color, lcd_param->f_size, len, STR_WELCOME);
    lcd_right_move(0, LCD_RIGHT_MOVE_EDN(lcd_param->w, (char *)STR_SMART_HOUSE, lcd_param->f_size), lcd_param->start_line + lcd_param->f_size * 1, lcd_param->f_color, lcd_param->b_color, lcd_param->f_size, STR_SMART_HOUSE);
    ia_lcd_reset(*lcd_param);
}

#define SOIL_HUMIDITY_V_MAX  1.8
#define SOIL_HUMIDITY_V_MIN  0.001
#define GET_SOIL_HUMIDITY(v)  v*100/(SOIL_HUMIDITY_V_MAX-SOIL_HUMIDITY_V_MIN)
/***************************************************************
* 函数名称: ia_get_soil_humidity
* 说    明: 获取土壤湿度
* 参    数: ia_soil_humidity_t *soil_humidity
* 返 回 值: float 电压值mv
***************************************************************/
float ia_get_soil_humidity(ia_soil_humidity_t *soil_humidity)
{
    float v = 0;
    
    for (int i = 0; i < 5; ++i)
    {
        v += ia_get_voltage(&soil_humidity->adc_dev);
    }
    v /= 5;
    soil_humidity->voltage = v * 1000;
    soil_humidity->value = GET_SOIL_HUMIDITY(v);
    soil_humidity->value = soil_humidity->value > 99.9 ? 99.9 : soil_humidity->value;
    return v;
}

/***************************************************************
* 函数名称: ia_get_light_intensity
* 说    明: 获取光照强度
* 参    数: ia_light_intensity_t *light_intensity
* 返 回 值: float 光照值lux
***************************************************************/
float ia_get_light_intensity(ia_light_intensity_t *light_intensity)
{
    uint8_t  recv_data[2] = {0};
    uint32_t receive_len = 2;
    
    if (light_intensity->i2c_dev.init == 0)
    {
        printf("I2C not init\n");
    }
    
    ia_start_bh1750(&light_intensity->i2c_dev);
    LOS_Msleep(180);
    
    LzI2cRead(light_intensity->i2c_dev.port, light_intensity->i2c_dev.slave_addr, recv_data, receive_len);
    light_intensity->value = (float)(((recv_data[0] << 8) + recv_data[1]) / 1.2);
    
    return light_intensity->value;
}

/***************************************************************
* 函数名称: ia_set_water_pump
* 说    明: 水泵控制
* 参    数: ia_water_pump_t *water_pump
*          SWITCH_STATUS_E status   OFF,关 ON,开
* 返 回 值: 无
***************************************************************/
void ia_set_water_pump(ia_water_pump_t *water_pump, SWITCH_STATUS_E status)
{
    if (status == ON)
    {
        ia_water_pump_on(water_pump);
    }
    else if (status == OFF)
    {
        ia_water_pump_off(water_pump);
    }
}

/***************************************************************
* 函数名称: ia_set_shed_cover
* 说    明: 棚罩控制
* 参    数: ia_shed_cover_t *shed_cover,
*          SWITCH_STATUS_E status  OFF,关 ON,开
* 返 回 值: 无
***************************************************************/
void ia_set_shed_cover(ia_shed_cover_t *shed_cover, SWITCH_STATUS_E status)
{
    if (status == ON)
    {
        ia_shed_cover_on(shed_cover);
    }
    else if (status == OFF)
    {
        ia_shed_cover_off(shed_cover);
    }
}

/***************************************************************
* 函数名称: ia_lcd_soil_humidity_display
* 说    明: LCD土壤湿度显示
* 参    数: ia_lcd_t *ia_lcd, ia_dev_t *ia_dev
* 返 回 值: 无
***************************************************************/
void ia_lcd_soil_humidity_display(ia_lcd_t *ia_lcd, ia_dev_t *ia_dev)
{
    ia_lcd_param_t *lcd = &ia_lcd->param;
    Printf_Lcd(0, lcd->start_line + lcd->f_size * 0, lcd->f_color, lcd->b_color, lcd->f_size, E_LCD_SCREEN_ALIGN_LEFT_NOP,
               "土壤湿度:%.1f%%", ia_dev->soil_humidity->value);
}

/***************************************************************
* 函数名称: ia_lcd_water_pump_display
* 说    明: LCD水泵状态显示
* 参    数: ia_lcd_t *ia_lcd, ia_dev_t *ia_dev
* 返 回 值: 无
***************************************************************/
void ia_lcd_water_pump_display(ia_lcd_t *ia_lcd, ia_dev_t *ia_dev)
{
    ia_lcd_param_t *lcd = &ia_lcd->param;
    Printf_Lcd(0, lcd->start_line + lcd->f_size * 1, lcd->f_color, lcd->b_color, lcd->f_size, E_LCD_SCREEN_ALIGN_LEFT_NOP,
               "水泵:    %s", ia_dev->water_pump->onoff == ON ? "运行" : "停止");
}

/***************************************************************
* 函数名称: ia_lcd_light_intensity_display
* 说    明: LCD光线强度显示
* 参    数: ia_lcd_t *ia_lcd, ia_dev_t *ia_dev
* 返 回 值: 无
***************************************************************/
void ia_lcd_light_intensity_display(ia_lcd_t *ia_lcd, ia_dev_t *ia_dev)
{
    ia_lcd_param_t *lcd = &ia_lcd->param;
    Printf_Lcd(0, lcd->start_line + lcd->f_size * 3, lcd->f_color, lcd->b_color, lcd->f_size, E_LCD_SCREEN_ALIGN_LEFT_NOP,
               "光线强度:%.1flux", ia_dev->light_intensity->value);
}

/***************************************************************
* 函数名称: ia_lcd_shed_cover_display
* 说    明: LCD棚罩状态显示
* 参    数: ia_lcd_t *ia_lcd, ia_dev_t *ia_dev
* 返 回 值: 无
***************************************************************/
void ia_lcd_shed_cover_display(ia_lcd_t *ia_lcd, ia_dev_t *ia_dev)
{
    ia_lcd_param_t *lcd = &ia_lcd->param;
    Printf_Lcd(0, lcd->start_line + lcd->f_size * 4, lcd->f_color, lcd->b_color, lcd->f_size, E_LCD_SCREEN_ALIGN_LEFT_NOP,
               "棚罩:    %s", ia_dev->shed_cover->onoff == ON ? "打开" : "关闭");
}

/***************************************************************
* 函数名称: ia_lcd_data_display
* 说    明: LCD数据初始化显示
* 参    数: ia_lcd_t *ia_lcd, ia_dev_t *ia_dev
* 返 回 值: 无
***************************************************************/
void ia_lcd_data_display(ia_lcd_t *ia_lcd, ia_dev_t *ia_dev)
{
    ia_lcd_soil_humidity_display(ia_lcd, ia_dev);
    ia_lcd_water_pump_display(ia_lcd, ia_dev);
    ia_lcd_light_intensity_display(ia_lcd, ia_dev);
    ia_lcd_shed_cover_display(ia_lcd, ia_dev);
}
